package com.oracle.calllog.analyze.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.Properties;

public class ConnectionPool {
	/*实现连接池在内存中只有一个(单例模式)*/
	private static ConnectionPool pool = new ConnectionPool();
	//用于缓存数据库连接的容器载体
	private LinkedList<Connection> conns = new LinkedList<Connection>();
	
	/**
	 * 单例模式的构造器，构造连接池时加载了驱动
	 */
	private ConnectionPool(){
		try {
			Class.forName(Constants.DRIVER_CLASS);
		} catch (ClassNotFoundException e) {
			System.err.println("检查jdbc依赖导入了吗？再检查一下驱动串写对了吗？");
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 获取唯一存在的那个连接池实例
	 * @return
	 */
	public static ConnectionPool getInstance(){
		return pool;
	}
	
	/**
	 * 获取连接，原则：池中有从池中捞，池中没有创建新的
	 * @return
	 */
	public synchronized Connection getConnection(){
		Connection conn = null;
		if(conns.size()>0){
			conn = conns.removeFirst();
		}else{
			try {
				Properties prop = new Properties();
				prop.setProperty("user", Constants.USER_NAME);
				prop.setProperty("password", Constants.USER_PWD);
				if(Constants.DB_TYPE.equals("phoenix")){
					prop.setProperty(Constants.PROPERTY_PHOENIX_KEY, Constants.PROPERTY_PHOENIX_VALUE);
				}
				conn = DriverManager.getConnection(Constants.CONNECTION_URL, prop);
			} catch (SQLException e) {
				System.err.println("检查一下URL串写对了吗？再检查一下用户名和密码都对吗？");
				e.printStackTrace();
			}
		}
		return conn;
	}
	
	
	/**
	 * 回收连接：池中没满往池中放，池中满了直接关
	 * @param conn
	 */
	public void revokeConnection(Connection conn){
		this.revokeConnection(null, null, conn);
	}
	
	/**
	 * 回收连接：池中没满往池中放，池中满了直接关
	 * @param stmt
	 * @param conn
	 */
	public void revokeConnection(Statement stmt, Connection conn){
		this.revokeConnection(null, stmt, conn);
	}
	
	/**
	 * 回收连接：池中没满往池中放，池中满了直接关
	 * @param rs
	 * @param stmt
	 * @param conn
	 */
	public void revokeConnection(ResultSet rs, Statement stmt, Connection conn){
		try {
			// 防止空指针异常的小技巧
			if (rs != null)
				rs.close();
			if (stmt != null)
				stmt.close();
			synchronized (conns) {
				if(conns.size()<Integer.valueOf(Constants.POOL_MAXSIZE)){
					conns.addLast(conn);
				}else{
					conn.close();
				}
			}
		} catch (SQLException e) {
			System.err.println("回收失败！");
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 开启指定连接的手动事务
	 */
	public void beginTransacation(Connection conn) {
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			System.err.println("开启手动事务失败");
			e.printStackTrace();
		}
	}

	/**
	 * 提交指定连接的事务
	 */
	public void commit(Connection conn) {
		try {
			conn.commit();
		} catch (SQLException e) {
			System.err.println("手动提交事务失败");
			e.printStackTrace();
		}
	}

	/**
	 * 回滚指定连接的事务
	 */
	public void rollback(Connection conn) {
		try {
			conn.rollback();
		} catch (SQLException e) {
			System.err.println("手动回滚事务失败");
			e.printStackTrace();
		}
	}
}
